using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Dimok.Web.UI {

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>	Grid view ex. </summary>
	///
	/// <remarks>	Dimon, 12/21/2010. </remarks>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	public partial class GridViewEx {

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Sets a selected. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="control">	The control. </param>
		/// <param name="unDo">			true to un do. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		private static void SetSelected(Control control, bool unDo) {
			if(control is WebControl && !(control is TextBox)) {
				WebControl wc = (WebControl)control;
				if(!unDo) {
					if(wc.Attributes["color"] == null) wc.Attributes.Add("color", wc.Style["color"]);
					else wc.Attributes["color"] = wc.Style["color"];
					//wc.Style.Add("color", "white");
				} else wc.Style["color"] = wc.Attributes["color"];
			}
			if(!control.HasControls()) return;
			foreach(Control c in control.Controls)
				SetSelected(c,unDo);
		}
		#region Inserboxes

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Clears the insert controls described by insertRow. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="insertRow">	The insert row. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		protected static void ClearInsertControls(GridViewRow insertRow){
			foreach(Control c in Find.ChildrenByType(insertRow,typeof(TextBox),typeof(DropDownList)))
				if(c is DropDownList) ((DropDownList)c).SelectedIndex = -1;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Extracts the row values described by insertRow. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="insertRow">	The insert row. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static IOrderedDictionary ExtractRowValues(GridViewRow insertRow) {
			if(insertRow == null) return new OrderedDictionary();
			//if(insertRow.RowType != DataControlRowType.Footer) throw new Exception("RowType must be " + DataControlRowType.Footer);
			OrderedDictionary tbList = new OrderedDictionary();
			foreach(TableCell cell in insertRow.Cells) {
				string ID = ((DataControlFieldCell)cell).ContainingField.SortExpression;
				List<Control> controls =
					Find.ChildrenByType(cell, typeof(TextBox), typeof(DropDownList), typeof(HiddenField), typeof(CheckBox), typeof(Label));
				foreach(Control control in cell.Controls) {
					try {
						TextBox tb = control as TextBox;
						if(tb != null) tbList.Add(tb.ID, tb.Text == "" ? null : tb.Text);
						DropDownList sel = control as DropDownList;
						if(sel != null) tbList.Add(sel.ID, sel.SelectedValue == "" ? null : sel.SelectedValue);
						HiddenField hdn = control as HiddenField;
						if(hdn != null) tbList.Add(hdn.ID, hdn.Value == "" ? null : hdn.Value);
						CheckBox chk = control as CheckBox;
						if(chk != null) tbList.Add(chk.ID, chk.Checked);
						Label lbl = control as Label;
						if(lbl != null && (lbl.ID + "") != "") {
							if(!tbList.Contains(ID)) tbList.Add(ID, lbl.Text);
							string fieldID = (lbl.Attributes["FieldIDName"] + "") != "" ? lbl.Attributes["FieldIDName"] : lbl.ID + "";
							string fieldValue = lbl.Attributes["FieldIDValue"];
							if(fieldID != "" && !tbList.Contains(fieldID) && fieldValue != null)
								tbList.Add(fieldID, fieldValue);
						}
					} catch {
						throw;
					}
				}
				try {
					if(ID != "" && !tbList.Contains(ID)) {
						DataControlFieldCell fieldCell = cell as DataControlFieldCell;
						if(typeof(BoundField).IsInstanceOfType(fieldCell.ContainingField) &&
								(((BoundField)fieldCell.ContainingField).DataField + "") == ID &&
								cell.Text != "&nbsp;" )
							tbList.Add(ID, cell.Text);
					}
				} catch {
					throw;
				}
			}
			return tbList;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Searches for the first filter row boxes. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <returns>	The found filter row boxes. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public IOrderedDictionary FindFilterRowBoxes() { return FindInsertRowBoxes(HeaderRow); }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Searches for the first insert row boxes. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="insertRow">	The insert row. </param>
		///
		/// <returns>	The found insert row boxes. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		protected static IOrderedDictionary FindInsertRowBoxes(GridViewRow insertRow) {
			if(insertRow == null) return new OrderedDictionary();
			//if(insertRow.RowType != DataControlRowType.Footer) throw new Exception("RowType must be " + DataControlRowType.Footer);
			OrderedDictionary tbList = new OrderedDictionary();
			foreach(TableCell cell in insertRow.Cells) {
				List<Control> controls =
					Find.ChildrenByType(cell, typeof(TextBox), typeof(DropDownList), typeof(HiddenField), typeof(CheckBox));
				foreach(Control control in controls) {
					TextBox tb = control as TextBox;
					if(tb != null) tbList.Add(tb.ID, tb.Text == "" ? null : tb.Text);
					DropDownList sel = control as DropDownList;
					if(sel != null) tbList.Add(sel.ID, sel.SelectedValue == "" ? null : sel.SelectedValue);
					HiddenField hdn = control as HiddenField;
					if(hdn != null) tbList.Add(hdn.ID, hdn.Value == "" ? null : hdn.Value);
					CheckBox chk = control as CheckBox;
					if(chk != null &&( chk.ID+"") != "") tbList.Add(chk.ID, chk.Checked);
				}
			}
			return tbList;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Sets a row boxes. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="insertRow">	The insert row. </param>
		/// <param name="filter">			The filter. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		protected static void SetRowBoxes(GridViewRow insertRow,IDictionary filter) {
			if(insertRow == null) return;
			foreach(TableCell cell in insertRow.Cells) {
				List<Control> controls =
					Find.ChildrenByType(cell, typeof(TextBox), typeof(DropDownList), typeof(HiddenField)/*beware of visibility checkbox, typeof(CheckBox)*/);
				foreach(Control control in controls) {
					string filterString = filter[control.ID] + "";// Regex.Match(filter[control.ID] + "", "^'?(.+?)'?$").Groups[1].Value;
					TextBox tb = control as TextBox;
					if (tb != null) {
						tb.Text = filterString;
						tb.ToolTip = (filterString == "" ? "" : filterString + Environment.NewLine) + tb.ToolTip;
					}
					DropDownList sel = control as DropDownList;
					if(sel != null ) sel.SelectedValue =filterString;
					HiddenField hdn = control as HiddenField;
					if(hdn != null) hdn.Value = filterString;
					CheckBox chk = control as CheckBox;
					if(chk != null) chk.Checked = bool.Parse(filterString);
				}
			}
		}
		#endregion

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets a column total. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="rows">		The rows. </param>
		/// <param name="column">	The column. </param>
		///
		/// <returns>	The column total. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static object GetColumnTotal(System.Data.DataRowCollection rows, string column) {
			decimal dd = 0;
			foreach (System.Data.DataRow row in rows) {
				if (row[column] == DBNull.Value) continue;
				decimal d;
				if (!decimal.TryParse(row[column] + "", out d)) return DBNull.Value;
				dd += d;
			}
			return dd != 0 ? (object)dd : (object)DBNull.Value;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Finds the columnaverage of the given arguments. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="rows">		The rows. </param>
		/// <param name="column">	The column. </param>
		///
		/// <returns>	The calculated column average. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public static object GetColumnAverage(System.Data.DataRowCollection rows, string column) {
			decimal dd = 0, count = 0;
			foreach (System.Data.DataRow row in rows) {
				if (row[column] == DBNull.Value) continue;
				decimal d;
				if (!decimal.TryParse(row[column] + "", out d)) return DBNull.Value;
				dd += d;
				count++;
			}
			return dd != 0 ? (object)(Math.Round(dd / count, 2)) : (object)DBNull.Value;
		}
	}
}
